import pandas as pd


def InstrumentsAvgAsBenchmark(params):

    database = params["Database"]
    datetime1 = params["DateTime1"]
    datatime2 = params["DateTime2"]
    instruments = params["Instruments"]

    #
    filter = {}
    gte = {"StdDateTime": {"$gte": datetime1}}
    lte = {"StdDateTime": {"$lte": datatime2}}
    filter["$and"] = [gte, lte]

    #
    filter["$or"] = []
    for instrument in instruments:
        symbol = instrument["Symbol"]
        filter["$or"].append({"Symbol":symbol})

    #
    returns = database.Find("Factor", "MonthlyReturn", filter, {"StdDateTime": 1})

    # ---Group by Symbols---
    print("Format Returns by Symbol", datetime.datetime.now())
    returnsBySymbol = {}
    for r in returns:
        symbol = r["Symbol"]
        stdDatetime = r["StdDateTime"]
        value = r["Value"]
        #if symbol not in validSymbols:
        #    continue
        if symbol not in returnsBySymbol.keys():
            returnsBySymbol[symbol] = []
        #
        returnsBySymbol[symbol].append([stdDatetime, value])

    #
    maxLength = 0
    maxLengthSymbol = None
    # ---找到最长那个序列，以之为基础---
    for symbol, returns in returnsBySymbol.items():
        if len(returns) > maxLength:
            maxLength = len(returns)
            maxLengthSymbol = symbol
    #
    df = pd.DataFrame(returnsBySymbol[maxLengthSymbol], columns=["StdDateTime", maxLengthSymbol])

    #
    for symbol, returns in returnsBySymbol.items():
        # don't duplicated
        if symbol == maxLengthSymbol:
            continue

        # Create Dataframe
        tempDf = pd.DataFrame(returns, columns=["StdDateTime", symbol])
        df = pd.merge(df, tempDf, on='StdDateTime', how='left')
    #
    return df


def SymbolAsBenchmark(params):
    #
    database = params["Database"]
    datetime1 = params["DateTime1"]
    datetime2 = params["DateTime2"]
    instruments = params["Instruments"]

    #
    filter = {"Symbol": instruments[0]["Symbol"]}
    gte = {"StdDateTime": {"$gte": datetime1}}
    lte = {"StdDateTime": {"$lte": datetime2}}
    filter["$and"] = [gte, lte]
    returns = database.Find("Factor", "MonthlyReturn", filter, {"StdDateTime": 1})

    #
    data = []
    for r in returns:
        symbol = r["Symbol"]
        stdDatetime = r["StdDateTime"]
        value = r["Value"]
        data.append([stdDatetime, value])

    #
    df = pd.DataFrame(data, columns=["StdDateTime", "BenchmarkReturn"])
    return df
